from .celery import app
import subprocess
import time
from datetime import datetime, timezone, timedelta


@app.task(name='command')
def command(*args):
    # security check
    if not args:
        raise Exception('agrs is empty')

    dangerous_chars = ['\n', ';', '&', '|', '{', '(', '\'', '"', '>', '<', '`', '[']
    for char in dangerous_chars:
        if char in args[0]:
            raise Exception('"{0}" contains dangerous char \'{1}\''.format(args[0], char))

    allowed_commands = ['admin-cmd.sh']
    cmd = (args[0].split())[0]
    if cmd not in allowed_commands:
        raise Exception(
            "you are using '{cmd}', for security, you can only use command in [ {cmds} ]".format_map(
                {"cmd": cmd, "cmds": ''.join(allowed_commands)}))

    # execute cmd
    try:
        return subprocess.check_output(args, shell=True, stderr=subprocess.PIPE, timeout=8 * 3600).decode()
    except subprocess.CalledProcessError as e:
        errmsg = ''
        if e.stderr:
            errmsg += e.stderr.decode()
        # non-zero exit status, but error message in stdout,not in stderr
        if e.stdout and len(e.stdout) < 4096:
            errmsg += e.stdout.decode()
        raise Exception(errmsg)


@app.task
def add(x, y):
    return x + y


@app.task
def echo(msg, timestamp=False):
    return "%s: %s" % (datetime.now(), msg) if timestamp else msg


@app.task
def sleep(seconds):
    time.sleep(seconds)


@app.task
def error(msg):
    raise Exception(msg)
